library IEEE;
use IEEE.std_logic_1164.all;
use work.state_pkg.all;


entity controller2 is
	port (	clk			: in	std_logic;
		reset			: in	std_logic;

		sensor_l		: in	std_logic;
		sensor_m		: in	std_logic;
		sensor_r		: in	std_logic;
		
		--do_cross : in std_logic;
		--do_find : in std_logic;

		count_in		: in	std_logic_vector (19 downto 0);
		count_reset		: out	std_logic;
		
		rover_direction : out direction_type;
		
		debug_led_1 : out std_logic;
		debug_led_2 : out std_logic;
		display_data	: out	std_logic_vector (7 downto 0);
		display_enable	: out	std_logic_vector (3 downto 0)
	);
end entity controller2;

architecture structural of controller2 is
  component main_state_ctrl is
	port (	clk			: in	std_logic;
		reset			: in	std_logic;
		
		continu : in std_logic;
		
		do_cross : in std_logic;
		do_find : in std_logic;

		sensor_l		: in	std_logic;
		sensor_m		: in	std_logic;
		sensor_r		: in	std_logic;
		
		go_search : out std_logic;
		go_track : out std_logic;
		go_cross : out std_logic;
		go_map : out std_logic;
		
		bin_state : out std_logic_vector(1 downto 0);
		reset_cross_mem : out std_logic;
		
		dbm : out string(1 downto 1)
	);
  end component;
    
  component track_state_ctrl is
	port (	clk			: in	std_logic;
		reset			: in	std_logic;

		sensor_l		: in	std_logic;
		sensor_m		: in	std_logic;
		sensor_r		: in	std_logic;
		
		continu : out std_logic;
		rover_direction : out direction_type;
		
		dbm : out string (2 downto 1)
	);
  end component;
  
  component map_state_ctrl is
	port (clk			: in	std_logic;
		reset			: in	std_logic;
		continu : out std_logic;
		rover_direction : out direction_type;
		
		dbm : out string (2 downto 1)
		);
	end component;
	component cross_mem is
	port (	clk			: in	std_logic;
		reset			: in	std_logic;

		sensor_l		: in	std_logic;
		sensor_m		: in	std_logic;
		sensor_r		: in	std_logic;
		
		L: out std_logic;
		R: out std_logic
	);
end component;
	
	component cross_state_ctrl is
	port (	clk			: in	std_logic;
		reset			: in	std_logic;

		sensor_l		: in	std_logic;
		sensor_m		: in	std_logic;
		sensor_r		: in	std_logic;
		R         : in std_logic;
		L         : in std_logic;
		
		
		continu : out std_logic;
		rover_direction : out direction_type;
		
		dbm : out string (2 downto 1)
	);
end component;
 
  component display_char is
	port (	clk			: in	std_logic;	
		reset			: in	std_logic;
		
		char0		: in character;
		char1		: in character;
		char2		: in character;
		char3		: in character;

		display_data	: out	std_logic_vector (7 downto 0);
		display_enable	: out	std_logic_vector (3 downto 0)
	);
  end component;
  component encoder_substates is
  port (    
    track_cont : in std_logic;
    search_cont : in std_logic;
    cross_cont : in std_logic;
    map_cont : in std_logic;
    
    track_dir : in direction_type;
    search_dir : in direction_type;
    cross_dir : in direction_type;
    map_dir : in direction_type;
    
    track_dbm : in string(2 downto 1);
    search_dbm : in string(2 downto 1);
    cross_dbm : in string(2 downto 1);
    map_dbm : in string(2 downto 1);
    
    state : in std_logic_vector(1 downto 0);
    
    
    continu : out std_logic;
    direction : out direction_type;
    dbm : out string(2 downto 1)
    
  );
  end component;
    
    signal continu_state : std_logic;
    
    signal go_search, go_track, go_cross, go_map : std_logic;
    
    signal dbm_main :string (1 downto 1);
    
    signal track_cont, search_cont, cross_cont, map_cont, L, R, go_left, go_right : std_logic;
    signal track_dir, search_dir, cross_dir, map_dir : direction_type;
    signal track_dbm, search_dbm, cross_dbm, map_dbm, dbm_sub : string(2 downto 1);
    signal bin_state_code : std_logic_vector(1 downto 0);
    signal reset_cross_mem: std_logic;

begin
    lbl_mctrl: main_state_ctrl PORT MAP(clk => clk,
                                        reset => reset,
                                        continu => continu_state,
                                        do_cross => '1',
                                        do_find => '0',
                                        sensor_l => sensor_l,
                                        sensor_m => sensor_m,
                                        sensor_r => sensor_r,
                                        go_search => go_search,
                                        go_track => go_track,
                                        go_cross => go_cross,
                                        go_map => go_map,
                                        bin_state => bin_state_code,
                                        reset_cross_mem => reset_cross_mem,
                                        dbm => dbm_main);
    lbl_track: track_state_ctrl PORT MAP (clk => clk, 
														reset => go_track,
														sensor_l => sensor_l,
														sensor_m => sensor_m,
														sensor_r => sensor_r,
                                
														continu => track_cont,
														rover_direction => track_dir,
														dbm => track_dbm);
										  
	 lbl_map: map_state_ctrl PORT MAP (		clk					=>		clk,
														reset					=>		go_map,
														continu				=>		map_cont,
														rover_direction 	=> 	map_dir,
														dbm					=>		map_dbm);
														
	 lbl_cross_mem: cross_mem PORT MAP(	clk					=> clk,
														reset					=> reset_cross_mem,

														sensor_l => sensor_l,
														sensor_m => sensor_m,
														sensor_r => sensor_r,
														
														L        =>	L,
														R     	=> R);

														
	 lbl_cross: cross_state_ctrl PORT MAP (clk => clk, 
														reset => go_cross,
														sensor_l => sensor_l,
														sensor_m => sensor_m,
														sensor_r => sensor_r,
														
														R        =>	R,
														L     	=> L,
                                
														continu => cross_cont,
														rover_direction => cross_dir,
														dbm => cross_dbm);
                                
                                
    lbl_encode: encoder_substates  PORT MAP ( track_cont => track_cont,
                                              search_cont => search_cont,
                                              cross_cont => cross_cont,
                                              map_cont => map_cont,
    
                                              track_dir => track_dir,
                                              search_dir => search_dir,
                                              cross_dir => cross_dir,
                                              map_dir => map_dir,
    
                                              track_dbm => track_dbm,
                                              search_dbm => search_dbm,
                                              cross_dbm => cross_dbm,
                                              map_dbm => map_dbm,
                                              state => bin_state_code,
    
    
                                              continu => continu_state,
                                              direction => rover_direction,
                                              dbm => dbm_sub);                     
                                        
    lbl_debug: display_char PORT MAP(clk => clk, reset => reset, 
                                     char0 => dbm_main(1),
                                     char1 => ' ',
                                     char2 => dbm_sub(2),
                                     char3 => dbm_sub(1),
                                     display_data => display_data,
                                     display_enable => display_enable );                                    
    

end architecture structural;
